<?php
/**
 * Класс для работы с виджетами
 * 
 * @category Phorm
 * @package Widget
 * @name /Phorm/Widget.php
 * @copyright phorm.ru
 * @since 10.12.2010
 * @author vladimir@kachalov.net
 */

class Phorm_Widget extends Phorm_Model {
	
	/**
	 * Устанавливает опции для текущего виджета
	 *  
	 * @param array $options Массив опций виджета
	 * 
	 * @return Phorm_Widget
	 */
	
	public function setOptions(array $options) {
		
		$this->_options = $options;
		
		return $this;
		
	}
	
	
	/**
	 * Устанавливает опции для текущего виджета
	 *  
	 * @param string $template Имя шаблона/папки_с_конфигом виджета
	 * @param string $context Имя контекста/xml_файла_с_конфигом виджета
	 * @return Phorm_Widget
	 */
	
	public function setSettings($template,$context) {
		
		$this->_settings = $this->getSettings($template,$context);
		
		return $this;
		
	}
	
	
	/**
	 * Возвращает массив опций для текущего виджета
	 * 
	 * @param string $template Имя шаблона/папки_с_конфигом виджета
	 * @param string $context Имя контекста/xml_файла_с_конфигом виджета
	 *  
	 * @return array
	 */
	
	protected function getSettings($template,$context) {
		
		if(!empty($template) && !empty($context)) {
			
			return Phorm_Config::xml('widgets/' . $template . '/' . $context . '.xml');
			
		}
		
		return false;
		
	}
	
	
	/**
	 * Возвращает список наборов виджетов
	 *
	 * @return array
	 */
	
	public function getWidgetsSetsList() {
		
		$select = $this->_db->select()
				-> from('pw_widgets_sets',array('setid','setname'))
				-> order('setid');
				
		return $this->_db->fetchPairs($select);
		
	}
	
	/**
	 * Возвращает список наборов виджетов с полными данными
	 * @todo Накинуть постраничную навигацию....
	 *
	 * @return array
	 */
	
	public function getWidgetsSetsFullList() {
		
		$select = $this->_db->select()
				-> from('pw_widgets_sets',new Zend_Db_Expr("SQL_CALC_FOUND_ROWS pw_widgets_sets.*, 'actions' actions"))
				-> order('setname')
				-> order('setid');
				
		return $this->_db->fetchAll($select);
		
	}
	
	
	/**
	 * Возвращает информацию о наборе виджетов
	 *
	 * @param int $setid Id набора виджетов
	 * @return array
	 */
	
	public function getWidgetsSetInfo($setid) {
		
		$select = $this->_db->select()
				-> from('pw_widgets_sets')
				-> where('setid=?',$setid);
				
		return $this->_db->fetchRow($select);
		
	}
	
	
	/**
	 * Возвращает список типов виджетов
	 *
	 * @return array
	 */
	
	public function getWidgetsTypes() {
		
		$select = $this->_db->select()
				-> from('pw_widgets_types',array('typeid','typename'))
				-> order('typename');
				
		return $this->_db->fetchPairs($select);
		
	}
	
	
	/**
	 * Возвращает список разделов
	 * 
	 * @param array $options Массив опций виджета
	 *  
	 * @return array
	 */
		
	protected function getCategoriesList($options=array()) {
			
		if(isset($options["categories"]) && !empty($options["categories"])) {
				
			$Categoryid  = isset($this->_params["categoryinfo"]) ? (int)$this->_params["categoryinfo"]["categoryid"] : 0;
			
			$select = $this->_db->select()
				-> from("pw_categories",array("categoryid"))
				-> where("isexist='yes'")
				-> order("cleft");
				
			if($this->getModule()!="control") $select -> where("visible='yes'");
				
			switch ($options["categories"]) {
					
				case "currentfull":
					
					$select -> where("cleft BETWEEN ".(int)$this->_params["categoryinfo"]["cleft"]." AND ".(int)$this->_params["categoryinfo"]["cright"]);
					return $this->_db->fetchCol($select);
						
					break;
						
				case "current":
						
					return array($Categoryid);
						
					break;
						
				case "full":
						
					return $this->_db->fetchCol($select);
						
					break;
						
				default:
						
					if(preg_match("#^[0-9]+(,[0-9]+)*$#",$options["categories"])) {
							
						return explode(",",$options["categories"]);
							
					}
					
			}
				
		}
			
		return array();	
			
	}
	
	
	/**
	 * Возвращает список макетов в виде массива конфигураций Zend_Config
	 *
	 * @return array
	 */
	
	public function getLayoutsList() {
		
		$path = APPLICATION_PATH . '/configs/layouts/';
		
		$handler = opendir($path);
		
		$masterfiles = array();
		
		while (($file = readdir($handler)) !== false) {
			if(strtolower(pathinfo($file, PATHINFO_EXTENSION))=='xml') {
				//$masterfiles[pathinfo($file,PATHINFO_FILENAME)] = new Zend_Config_Xml($path . $file);
				$masterfiles[pathinfo($file,PATHINFO_FILENAME)] = Phorm_Config::xml('/layouts/' . $file);
			}
		}
			
		closedir($handler);
		
		return $masterfiles;
		
	}
	
	
	/**
	 * Возвращает список существующих в системе ролей
	 * 
	 * @return array
	 */
		
	function getRolesList() {
		
		$select = $this->_db->select()
				-> from('pw_roles',array('roleid','rolename'))
				-> where('isexist=?','yes')
				-> order('rolename');
			
		return $this->_db->fetchPairs($select);
			
	}
	
	
	/**
	 * Возвращает информацию о типе виджета
	 *
	 * @param int $typeid
	 * 
	 * @return array | false
	 */
	
	public function getWidgetTypeInfo($typeid) {
		
		$select = $this->_db->select()
				-> from('pw_widgets_types')
				-> where('typeid=?',$typeid);
				
		return $this->_db->fetchRow($select);
		
	}
	
	
	/**
	 * Возвращает форму добавления/редактирования виджета
	 *
	 * @param string $section Секция xml-файла
	 * @param array $TypeInfo Массив данных о типе виджета (для расширения формы)
	 * @return Phorm_Form
	 */
	
	public function getWidgetForm($section = 'add', $TypeInfo = array()) {
		
		/**
		 * Расширяем базовую форму формой виджета через аналогичную секцию (add или edit)
		 */
		
		$files = array('forms/control/widgets.xml');
		if(!empty($TypeInfo)) $files[] = 'widgets/'.$TypeInfo['template'].'/'.$TypeInfo['context'].'.xml';
		
		/**
		 * Инициализируем объект формы
		 */
		
		$form = new Phorm_Form($files,$section);
		
		/**
		 * Добавляем валидацию на тип элемента CategoriesMultiSelect
		 */
		
		foreach ($form->getElements() as $element) {
			if ($element->getType()=='Phorm_Form_Element_CategoriesMultiSelect') {
				$haystack = $element->getMultiOptions();
				foreach ($haystack as $key=>$val) {
					$haystack[$key] = is_array($val) ? $val['categoryid'] : $key; 
				}
				$element->addValidator("InArray",true,array("haystack" => $haystack));
				continue;
			}
		}
		
		/**
		 * Добавляем данные для элементов формы
		 */
		
		if(isset($form->typeid)) $form->typeid->options = array(0=>$this->_translate->_('---Выберите---')) + $this->getWidgetsTypes();
		
		if(isset($form->acl)) $form->acl->options = $this->getRolesList();
		
		return $form;
		
	}
	
	
	/**
	 * Возвращает форму добавления/редактирования наборов
	 *
	 * @param string $section Секция xml-файла
	 * @param string $widgets JSON-строка виджетов в наборе (в базе они в виде JSON-строки хранятся)
	 * @return Phorm_Form
	 */
	
	public function getWidgetSetForm($section = 'setadd', $widgets = null) {
		
		$form = new Phorm_Form('forms/control/widgets.xml',array('section'=>$section));
		
		/**
		 * Добавляем данные для элементов формы (Список макетов и список виджетов в выбранном наборе)
		 */
		
		if(isset($form->layoutname)) $form->layoutname->makets = $this->getLayoutsList();
		if(isset($form->layoutname) && !is_null($widgets)) $form->layoutname->widgets = $widgets;
		
		return $form;
		
	}
	
	
	/**
	 * Сохраняет набор виджетов в базе
	 *
	 * @param array $data Данные формы
	 * @return array | false
	 */
	
	public function saveWidgetsSet($data) {
		
		$this->_db->beginTransaction();
		
		try {
			
			$data['widgets'] = Zend_Json_Encoder::encode($data['widgets']);
		
			if(isset($data['setid']) && $data['setid']>0) {
				
				// UPDATE
				$this->_db->update('pw_widgets_sets',$data,'setid='.(int)$data['setid']);
				
			} else {
				
				// INSERT
				$this->_db->insert('pw_widgets_sets',$data);
				$data['setid'] = $this->_db->lastInsertId();
				
			}
			
			$this->_db->commit();
			
			/**
			 * Очистка кеша 
			 */
			$this->getCache('widgets')->clean();
			
			return $data;
		
		} catch (Exception $e) {
			
			$this->_db->rollBack();	
			$this->_errors[] = $e->getMessage();
				
			return false;
			
		}
		
		return false;
		
	}
		
}